/****************************************************************
 *  This file created by writerB.php on 03/08/2007 at 14:36:22  *
 ****************************************************************
 *  writerB.php created by Tonk (tonk@ctonk.com) in 2007        *
 ****************************************************************
 *                 General Document Information
 *
 *  File Name: exit.cpp
 *  Class Name: Exit
 *  Data members: 9
 *  Notes:
 ****************************************************************/

#include <iostream>
#include <fstream>
#include "exit.h"
#include "definitions.h"
#include "log.h"
#include "stringutil.h"



int Exit::numExits = 0;
int Exit::exitIndex = 0;


// Default constructor...
Exit::Exit() {
	setExitID( ++exitIndex );
	setVnum( 0 );
	setPoint( 0 );
	setKey( 0 );
	setFlags( 0 );
	setThere( false );
	setDoor( false );
	setOpen( false );
	setLock( false );
	setLocked( false );
	// Increment the object count...
	numExits++;
}

// Additional constructors...

// Copy constructor (Doesn't change _ExitID)...
Exit::Exit( const Exit& ref ) {
	setExitID( ++exitIndex );
	setVnum( ref.getVnum() );
	setPoint( ref.getPoint() );
	setKey( ref.getKey() );
	setFlags( ref.getFlags() );
	setThere( ref.getThere() );
	setDoor( ref.getDoor() );
	setOpen( ref.getOpen() );
	setLock( ref.getLock() );
	setLocked( ref.getLocked() );
	// Increment the object count...
	numExits++;
}

// Destructor...
Exit::~Exit() {
	// Decrement the object count...
	numExits--;
}

// Assignment operator (Doesn't change _ExitID)...
Exit& Exit::operator = ( const Exit& ref ) {
	setVnum( ref.getVnum() );
	setPoint( ref.getPoint() );
	setKey( ref.getKey() );
	setFlags( ref.getFlags() );
	setThere( ref.getThere() );
	setDoor( ref.getDoor() );
	setOpen( ref.getOpen() );
	setLock( ref.getLock() );
	setLocked( ref.getLocked() );
	return *this;
}

// Equality operator (Doesn't compare _ExitID)...
bool Exit::operator == ( const Exit& ref ) const {
	return	(
		   getVnum() == ref.getVnum()
		&& getPoint() == ref.getPoint()
		&& getKey() == ref.getKey()
		&& getFlags() == ref.getFlags()
		&& getThere() == ref.getThere()
		&& getDoor() == ref.getDoor()
		&& getOpen() == ref.getOpen()
		&& getLock() == ref.getLock()
		&& getLocked() == ref.getLocked()
		);
}

// Less than operator (Compares _ExitID)...
bool Exit::operator < ( const Exit& ref ) const {
	return ( getExitID() < ref.getExitID() );
}

// Greater than operator (Compares _ExitID)...
bool Exit::operator > ( const Exit& ref ) const {
	return ( getExitID() > ref.getExitID() );
}

// Protected Methods...
void Exit::setExitID( const int& ExitID ) {
	_ExitID = ExitID;
}

// Public accessor methods...
int Exit::getExitID( void ) const {
	return _ExitID;
}

void Exit::setVnum( const unsigned& vnum ) {
	_vnum = vnum;
	return;
}

unsigned Exit::getVnum( void ) const {
	return _vnum;
}

void Exit::setPoint( const unsigned& point ) {
	_point = point;
	return;
}

unsigned Exit::getPoint( void ) const {
	return _point;
}

void Exit::setKey( const unsigned& key ) {
	_key = key;
	return;
}

unsigned Exit::getKey( void ) const {
	return _key;
}

void Exit::setFlags( const unsigned& flags ) {
	_flags = flags;
	return;
}

unsigned Exit::getFlags( void ) const {
	return _flags;
}

void Exit::setThere( const bool& there ) {
	setFlags( ( there ) ? (getFlags() | EXIT_FLAG_THERE) : ((~EXIT_FLAG_THERE) & getFlags()) );
	return;
}

bool Exit::getThere( void ) const {
	return ( (_flags & EXIT_FLAG_THERE) == EXIT_FLAG_THERE ) ? true : false;
}

void Exit::setDoor( const bool& door ) {
	setFlags( ( door ) ? (getFlags() | EXIT_FLAG_DOOR) : ((~EXIT_FLAG_DOOR) & getFlags()) );
	return;
}

bool Exit::getDoor( void ) const {
	return ( (_flags & EXIT_FLAG_DOOR) == EXIT_FLAG_DOOR) ? true : false;
}

void Exit::setOpen( const bool& open ) {
	setFlags( ( open ) ? (getFlags() | EXIT_FLAG_OPEN) : ((~EXIT_FLAG_OPEN) & getFlags()) );
	return;
}

bool Exit::getOpen( void ) const {
	return ( (_flags & EXIT_FLAG_OPEN) == EXIT_FLAG_OPEN) ? true : false;
}

void Exit::setLock( const bool& lock ) {
	setFlags( ( lock ) ? (getFlags() | EXIT_FLAG_LOCK) : ((~EXIT_FLAG_LOCK) & getFlags()) );
	return;
}

bool Exit::getLock( void ) const {
	return ( (_flags & EXIT_FLAG_LOCK) == EXIT_FLAG_LOCK) ? true : false;
}

void Exit::setLocked( const bool& locked ) {
	setFlags( ( locked ) ? (getFlags() | EXIT_FLAG_LOCKED) : ((~EXIT_FLAG_LOCKED) & getFlags()) );
	return;
}

bool Exit::getLocked( void ) const {
	return ( (_flags & EXIT_FLAG_LOCKED) == EXIT_FLAG_LOCKED) ? true : false;
}

// General methods...
void Exit::Save( std::ofstream& write ) {
	write	<< getThere() << ' ' << getPoint() << ' ' << getDoor() << ' '
			<< getOpen() << ' ' << getLock() << ' ' << getLocked() << ' '
			<< getKey() << ' ' << getFlags() << ' ';
	return;
}

void Exit::Load( std::ifstream& read ) {
	int itemp = 0;
	bool btemp = false;

	read >> btemp; setThere( btemp );
	read >> itemp; setPoint( itemp );
	read >> btemp; setDoor( btemp );
	read >> btemp; setOpen( btemp );
	read >> btemp; setLock( btemp );
	read >> btemp; setLocked( btemp );
	read >> itemp; setKey( itemp );
	read >> itemp; setFlags( itemp );

	return;
}

// Static methods...
std::string Exit::direction2string( const unsigned& direction ) {
	switch ( direction ) {
		case 0: return "North";
		case 1: return "East";
		case 2: return "South";
		case 3: return "West";
		case 4: return "Up";
		case 5: return "Down";
		default:
			std::string message;
			message << "Default hit in Exit::direction2string() in " << __FILE__ << " line " << __LINE__;
			log( message, SERVER );
			return "{Rerror{x";
	}
}

unsigned Exit::string2direction( const std::string& direction ) {
	if ( strstr( "north", direction ) )
		return NORTH;
	else if ( strstr( "east", direction ) )
		return EAST;
	else if ( strstr( "south", direction ) )
		return SOUTH;
	else if ( strstr( "west", direction ) )
		return WEST;
	else if ( strstr( "up", direction ) )
		return UP;
	else if ( strstr( "down", direction ) )
		return DOWN;
	else
		return -1;
}

unsigned Exit::inverse( const unsigned& direction ) {
	// This function returns the inverse of the given direction.
	switch ( direction ) {
		case NORTH: return SOUTH;
		case EAST: return WEST;
		case SOUTH: return NORTH;
		case WEST: return EAST;
		case UP: return DOWN;
		case DOWN: return UP;
		default: return -1;
	}
}

// Associated operators...
std::ostream& operator << ( std::ostream& write, Exit& exit ) { // associated
	write	<< exit.getThere() << ' ' << exit.getPoint() << ' ' << exit.getDoor() << ' '
			<< exit.getOpen() << ' ' << exit.getLock() << ' ' << exit.getLocked() << ' '
			<< exit.getKey() << ' ' << exit.getFlags() << ' ';
	return write;
}

std::ostream& operator << ( std::ostream& write, Exit* exit ) { // associated
	return ( write << *exit );
}

std::istream& operator >> ( std::istream& read, Exit& exit ) { // associated
	int itemp = 0;
	bool btemp = false;

	read >> btemp; exit.setThere( btemp );
	read >> itemp; exit.setPoint( itemp );
	read >> btemp; exit.setDoor( btemp );
	read >> btemp; exit.setOpen( btemp );
	read >> btemp; exit.setLock( btemp );
	read >> btemp; exit.setLocked( btemp );
	read >> itemp; exit.setKey( itemp );
	read >> itemp; exit.setFlags( itemp );

	return read;
}

std::istream& operator >> ( std::istream& read, Exit* exit ) { // associated
	return ( read >> *exit );
}
